From a408ad0bfb2a3c1631de86a62a75732d452b7017 Mon Sep 17 00:00:00 2001 From: Elvis Stansvik Date: Sat, 6 Aug 2022 00:12:19 +0200 Subject: [PATCH] Add upstream fix for shader crash with multivolume --- debian/patches/120_fix_shader_crash.patch | 163 ++++++++++++++++++++++ debian/patches/series | 1 + 2 files changed, 164 insertions(+) create mode 100644 debian/patches/120_fix_shader_crash.patch diff --git a/debian/patches/120_fix_shader_crash.patch b/debian/patches/120_fix_shader_crash.patch new file mode 100644 index 000000000..69c3f6bb8 --- /dev/null +++ b/debian/patches/120_fix_shader_crash.patch @@ -0,0 +1,163 @@ +commit bc4d0fec4f791fb198ff316849aaf3faba24b45a +Author: Gaspard Thevenon +Date: Thu Feb 10 10:19:39 2022 +0100 + + Fix shader crash in Multi Volume Rendering without GradientTF + + When using OpenGLGPUVolumeRayCastMapper with a MultiVolume, + not specifying a gradient opacity TF produced an error in + the composed shader (no argument would be given to functions which expected one), + and nothing was rendered, although this TF is supposed to be optional. + + This commit fixes this by adding tests during the declarations of + those functions inside the shader, and by changing their signatures as needed. + Therefore, when no gradient opacity TF is given, no argument is expected + and none is given. + +diff --git a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx +index cdcec460ef..dfc65de04b 100644 +--- a/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx ++++ b/Rendering/VolumeOpenGL2/vtkOpenGLGPUVolumeRayCastMapper.cxx +@@ -2415,7 +2415,8 @@ void vtkOpenGLGPUVolumeRayCastMapper::ReplaceShaderCompute( + vtkvolume::ComputeGradientOpacityMulti1DDecl(this->AssembledInputs)); + + vtkShaderProgram::Substitute(fragmentShader, "//VTK::ComputeColor::Dec", +- vtkvolume::ComputeColorMultiDeclaration(this->AssembledInputs)); ++ vtkvolume::ComputeColorMultiDeclaration( ++ this->AssembledInputs, vol->GetProperty()->HasGradientOpacity())); + + vtkShaderProgram::Substitute(fragmentShader, "//VTK::ComputeLighting::Dec", + vtkvolume::ComputeLightingMultiDeclaration(ren, this, vol, numComps, independentComponents, +@@ -2970,6 +2971,23 @@ bool vtkOpenGLGPUVolumeRayCastMapper::vtkInternal::UpdateInputs(vtkRenderer* ren + this->ForceTransferInit(); + } + ++ if (this->MultiVolume) ++ { ++ bool hasGradient = this->Parent->AssembledInputs[0].Volume->GetProperty()->HasGradientOpacity(); ++ for (auto& item : this->Parent->AssembledInputs) ++ { ++ if (item.second.Volume->GetProperty()->HasGradientOpacity() != hasGradient) ++ { ++ vtkGenericWarningMacro( ++ "Current implentation of vtkOpenGLGPUVolumeRayCastMapper does not support MultiVolume " ++ "where some volumes have a gradient opacity function and some others don't. " ++ "Rendering of the MultiVolume is disabled."); ++ success = false; ++ break; ++ } ++ } ++ } ++ + return success; + } + +@@ -3106,7 +3124,10 @@ void vtkOpenGLGPUVolumeRayCastMapper::GPURender(vtkRenderer* ren, vtkVolume* vol + this->Impl->MultiVolume = multiVol && this->GetInputCount() > 1 ? multiVol : nullptr; + + this->Impl->ClearRemovedInputs(renWin); +- this->Impl->UpdateInputs(ren, vol); ++ if (!this->Impl->UpdateInputs(ren, vol)) ++ { ++ return; ++ } + this->Impl->UpdateSamplingDistance(ren); + this->Impl->UpdateTransfer2DYAxisArray(ren, vol); + this->Impl->UpdateTransferFunctions(ren); +diff --git a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h +index 766f36ab63..3406bfb431 100644 +--- a/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h ++++ b/Rendering/VolumeOpenGL2/vtkVolumeShaderComposer.h +@@ -1054,10 +1054,24 @@ std::string ComputeLightingMultiDeclaration(vtkRenderer* vtkNotUsed(ren), vtkVol + int lightingComplexity) + { + vtkVolumeProperty* volProperty = vol->GetProperty(); +- std::string shaderStr = std::string("\ ++ ++ std::string shaderStr = std::string(); ++ ++ // if no gradient TF is needed, don't add it into the function signature ++ if (volProperty->HasGradientOpacity()) ++ { ++ shaderStr += std::string("\ + \nvec4 computeLighting(vec3 texPos, vec4 color, const in sampler2D gradientTF, const in sampler3D volume, const int volIdx, int component)\ + \n {\ + \n vec4 finalColor = vec4(0.0);"); ++ } ++ else ++ { ++ shaderStr += std::string("\ ++ \nvec4 computeLighting(vec3 texPos, vec4 color, const in sampler3D volume, const int volIdx, int component)\ ++ \n {\ ++ \n vec4 finalColor = vec4(0.0);"); ++ } + + // Shading for composite blending only + int const shadeReqd = volProperty->GetShade() && +@@ -1243,7 +1257,8 @@ std::string ComputeColorDeclaration(vtkRenderer* vtkNotUsed(ren), + } + + //-------------------------------------------------------------------------- +-std::string ComputeColorMultiDeclaration(vtkOpenGLGPUVolumeRayCastMapper::VolumeInputMap& inputs) ++std::string ComputeColorMultiDeclaration( ++ vtkOpenGLGPUVolumeRayCastMapper::VolumeInputMap& inputs, bool useGradientTF) + { + std::ostringstream ss; + int i = 0; +@@ -1274,13 +1289,28 @@ std::string ComputeColorMultiDeclaration(vtkOpenGLGPUVolumeRayCastMapper::Volume + } + else + { +- ss << "vec4 computeColor(vec3 texPos, vec4 scalar, float opacity, const in sampler2D colorTF, " +- "const in sampler2D gradientTF, const in sampler3D volume, const int volIdx)\n" +- "{\n" +- " return clamp(computeLighting(texPos, vec4(texture2D(colorTF,\n" +- " vec2(scalar.w, 0.0)).xyz, opacity), gradientTF, volume, " +- "volIdx, 0), 0.0, 1.0);\n" +- "}\n"; ++ if (useGradientTF) ++ { ++ ss ++ << "vec4 computeColor(vec3 texPos, vec4 scalar, float opacity, const in sampler2D colorTF, " ++ "const in sampler2D gradientTF, const in sampler3D volume, const int volIdx)\n" ++ "{\n" ++ " return clamp(computeLighting(texPos, vec4(texture2D(colorTF,\n" ++ " vec2(scalar.w, 0.0)).xyz, opacity), gradientTF, volume, " ++ "volIdx, 0), 0.0, 1.0);\n" ++ "}\n"; ++ } ++ else ++ { ++ ss ++ << "vec4 computeColor(vec3 texPos, vec4 scalar, float opacity, const in sampler2D colorTF, " ++ "const in sampler3D volume, const int volIdx)\n" ++ "{\n" ++ " return clamp(computeLighting(texPos, vec4(texture2D(colorTF,\n" ++ " vec2(scalar.w, 0.0)).xyz, opacity), volume, " ++ "volIdx, 0), 0.0, 1.0);\n" ++ "}\n"; ++ } + } + + return ss.str(); +@@ -1828,14 +1858,18 @@ std::string ShadingMultipleInputs( + + if (property->GetTransferFunctionMode() == vtkVolumeProperty::TF_1D) + { ++ std::string gradientopacity_param = (property->HasGradientOpacity()) ++ ? input.GradientOpacityTablesMap[0] + std::string(", ") ++ : std::string(); ++ + toShaderStr << " g_srcColor.a = computeOpacity(scalar," + << input.OpacityTablesMap[0] + << ");\n" + " if (g_srcColor.a > 0.0)\n" + " {\n" + " g_srcColor = computeColor(texPos, scalar, g_srcColor.a, " +- << input.RGBTablesMap[0] << ", " << input.GradientOpacityTablesMap[0] << ", " +- << "in_volume[" << i << "], " << i << ");\n"; ++ << input.RGBTablesMap[0] << ", " << gradientopacity_param << "in_volume[" << i ++ << "], " << i << ");\n"; + + if (property->HasGradientOpacity()) + { diff --git a/debian/patches/series b/debian/patches/series index ee1cfee67..1efd5d331 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -11,3 +11,4 @@ 98_fix_mpi4py.py 99_fix_ftbfs.patch 110_vtk9_netcdf.patch +120_fix_shader_crash.patch -- 2.30.2